/* eslint-disable */
// import {
//     GeometryAttribute, Geometry, ComponentDatatype, VertexArray,
//     BufferUsage, ShaderProgram, RenderState,PixelDatatype,PixelFormat,
//     Pass,destroyObject,DrawCommand,Texture
// } from 'cesium'

let { GeometryAttribute } = Cesium
let { Geometry } = Cesium
let { ComponentDatatype } = Cesium
let { VertexArray } = Cesium
let { BufferUsage } = Cesium
let { ShaderProgram } = Cesium
let { RenderState } = Cesium
let { PixelDatatype } = Cesium
let { PixelFormat } = Cesium
let { Pass } = Cesium
let { destroyObject } = Cesium
let { DrawCommand } = Cesium
let { Texture } = Cesium

export default class CustomPrimitive {
    constructor(options) {
        this.geometry = options.geometry
        this.attributeLocations = options.attributeLocations
        this.primitiveType = options.primitiveType
        this.vShader = options.vShader
        this.fShader = options.fShader
        this.renderState = options.renderState
        this.imageTexAry = options.imageTexAry
        this.flipY = options.flipY
        this.uniformMapOrg = options.uniformMap
        this.show = true
        this.commandToExecute = undefined
    }

    getGeometry(positionAry, clOrStAry, indicesAry, isTex) {
        const geometryAttributes = {
            position: new GeometryAttribute({
                componentDatatype: ComponentDatatype.FLOAT,
                componentsPerAttribute: 3,
                values: new Float32Array(positionAry)
            })
        }

        const geometryAttribute = {
            componentDatatype: ComponentDatatype.FLOAT,
            componentsPerAttribute: 2,
            values: new Float32Array(clOrStAry)
        }
        if (isTex) {
            geometryAttributes.st = new GeometryAttribute(geometryAttribute)
        } else {
            geometryAttribute.componentsPerAttribute = 4
            geometryAttributes.color = new GeometryAttribute(geometryAttribute)
        }

        return new Geometry({
            attributes: new GeometryAttributes(geometryAttributes),
            indices: new Uint32Array(indicesAry)
        })
    }

    createCommand(context) {
        // context = viewer.scene._context
        const vertexArray = VertexArray.fromGeometry({
            context: context,
            geometry: this.geometry,
            attributeLocations: this.attributeLocations,
            bufferUsage: BufferUsage.STATIC_DRAW,
        })
        const shaderProgram = ShaderProgram.fromCache({
            context: context,
            attributeLocations: this.attributeLocations,
            vertexShaderSource: this.vShader,
            fragmentShaderSource: this.fShader
        })
        const renderState = RenderState.fromCache(this.renderState)
        const modelView = context.uniformState.modelView
        const projection = context.uniformState.projection
        const uniformMap = {
            modelViewMatrix: function () {
                return modelView
            },
            projectionMatrix: function () {
                return projection
            }
        }

        if (this.uniformMapOrg) {
            this.uniformMapOrg.forEach(function (value, key) {
                uniformMap[key] = value
            })
        }

        if (this.imageTexAry && this.imageTexAry.length > 0) {
            for (let i = 0; i < this.imageTexAry.length; i++) {
                const colorTexture = new Texture({
                    context: context,
                    width: context.drawingBufferWidth,
                    height: context.drawingBufferHeight,
                    pixelFormat: PixelFormat.RGBA,
                    pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
                    source: this.imageTexAry[i],
                    flipY: this.flipY
                })
                uniformMap["colorTexture" + i] = function () {
                    return colorTexture
                }
            }
        }

        return new DrawCommand({
            vertexArray: vertexArray,
            primitiveType: this.primitiveType,
            uniformMap: uniformMap,
            shaderProgram: shaderProgram,
            renderState: renderState,
            pass: Pass.OPAQUE
        })
    }

    isDestroyed() {
        return false
    }

    destroy() {
        if (this.commandToExecute) {
            this.commandToExecute.shaderProgram = this.commandToExecute.shaderProgram && this.commandToExecute.shaderProgram.destroy()
        }
        this.commandToExecute = undefined
        return destroyObject(this)
    }

    update(frameState) {
        if (!this.show) {
            return
        }
        if (!this.commandToExecute) {
            this.commandToExecute = this.createCommand(frameState.context)
        }
        frameState.commandList.push(this.commandToExecute)
    }

}


